/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stendcontrol;

import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author minaev
 */
public class DataTract {

    UdpServer udp_serv;
    Thread t_udp_serv;
    MessageBuilder msg_bld;
    Thread t_msg_bld;
    UdpImplementer udpImpl;
    SensorInformer sen_inf;
    StendControlAPI sc_api;
    Experiment cur_exp = null;
    boolean started = false;

    public DataTract() {
        Configurator cnf = Configurator.getConf();
        try {
            udp_serv = new UdpServer(
                    (String) cnf.getProperty(Configurator.UDP_OUT_IP),
                    (Integer) cnf.getProperty(Configurator.UDP_IN_PORT),
                    (Integer) cnf.getProperty(Configurator.UDP_OUT_PORT));
        } catch (UnknownHostException ex) {
            StendLogger.log(StendLogger.MSG_ERROR, "Unknown Host UDP Server:"
                    + ex.getMessage());
        } catch (SocketException ex) {
            StendLogger.log(StendLogger.MSG_ERROR, "Socket Exception UDP "
                    + "Server:" + ex.getMessage());
        }

        msg_bld = new MessageBuilder();
        sen_inf = new SensorInformer(
                CoefConfigurator.getConf().getSensorCoef0(),
                CoefConfigurator.getConf().getSensorCoefProp());


        udp_serv.addTransmitListener(msg_bld);
        udp_serv.addTransmitListener(sen_inf);

        udpImpl = new UdpImplementer(udp_serv);
        sc_api = new StendControlAPI(udpImpl, sen_inf);
        t_udp_serv = new Thread(udp_serv);

        msg_bld.addMessageListener(sc_api);

    }

    public void initDataTract() {
        udp_serv.startTransmitToExp();
        t_udp_serv.start();
        t_msg_bld = new Thread(msg_bld);
        t_msg_bld.start();
        /*sc_api.setResearchType(StendControlAPI.TYPE_RESEARCH_TIME);
         try {
         Thread.sleep(100);
         } catch (InterruptedException ex) {
         Logger.getLogger(DataTract.class.getName()).log(Level.SEVERE, null, ex);
         }
         sc_api.setResearchType(StendControlAPI.TYPE_RESEARCH_NONE);*/
        //sc_api.goToTargetPosition(3, 32000);
    }

    public void setCurExp(Experiment cur_exp) {

        this.cur_exp = cur_exp;
        this.cur_exp.open();

    }

    private void resetMsgBuilder() {
        msg_bld.stopBuilding();
        try {
            t_msg_bld.join();
        } catch (InterruptedException ex) {
            StendLogger.log(StendLogger.MSG_ERROR, "Exception occured while try"
                    + "ing to join: " + ex.getMessage());
        }
        msg_bld.removeAllMessageListener();
        msg_bld.addMessageListener(sc_api);

        t_msg_bld = new Thread(msg_bld);
    }

    public void startBuildExp() {
        if (!started) {
            if (cur_exp != null) {
                resetMsgBuilder();
                msg_bld.addMessageListener(cur_exp);
                t_msg_bld.start();
                started = true;
            } else {
                StendLogger.log(StendLogger.MSG_ERROR, "Current experement is "
                        + "null");
            }
        } else {
            StendLogger.log(StendLogger.MSG_WARNING, "Starting started process "
                    + "DataTract");
        }
    }

    public void stopBuildExp() {
        if (cur_exp != null) {
            resetMsgBuilder();
            cur_exp.setExpEngine(sc_api.getCurrentEngine());
            cur_exp.close();
            cur_exp.updateDataSensors();

            t_msg_bld.start();
            started = false;
        } else {
            StendLogger.log(StendLogger.MSG_ERROR, "Current experement is "
                    + "null");
        }
    }

    public boolean isStarted() {
        return started;
    }

    public StendControlAPI getStendControlApi() {
        return sc_api;
    }

    public SensorInformer getSensorInformer() {
        return sen_inf;
    }

    public Experiment getCurExp() {
        return cur_exp;
    }

    public MessageBuilder getMsgBuilder() {
        return msg_bld;
    }

    public UdpServer getUDPServer() {
        return udp_serv;
    }
}
